package com.ziven.common.widget.value;

import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.DimenRes;
import androidx.annotation.NonNull;

import com.ziven.common.widget.WidgetUtils;
import com.ziven.easygo.util.EasyUtils;
import com.ziven.easygo.util.ResourceUtils;
import com.ziven.easygo.util.ViewHelper;

/**
 * @author Ziven
 */
public final class Margin extends MixValue {

    public static Margin topDimenId(@DimenRes int topDimenId) {
        return size(
                DimenValue.topDimenId(topDimenId)
        );
    }

    public static Margin bottomDimenId(@DimenRes int bottomDimenId) {
        return size(
                DimenValue.bottomDimenId(bottomDimenId)
        );
    }

    public static Margin topBottomDimenId(@DimenRes int marginDimenId) {
        int dimen = ResourceUtils.getDimen(marginDimenId);
        return topBottom(dimen, dimen);
    }

    public static Margin topBottomDimenId(@DimenRes int topDimenId,
                                          @DimenRes int bottomDimenId) {
        return size(
                DimenValue.topDimenId(topDimenId),
                DimenValue.bottomDimenId(bottomDimenId)
        );
    }

    public static Margin startDimenId(@DimenRes int startDimenId) {
        return size(
                DimenValue.startDimenId(startDimenId)
        );
    }

    public static Margin endDimenId(@DimenRes int endDimenId) {
        return size(
                DimenValue.endDimenId(endDimenId)
        );
    }

    public static Margin startEndDimenId(@DimenRes int marginDimenId) {
        int dimen = ResourceUtils.getDimen(marginDimenId);
        return startEnd(dimen, dimen);
    }

    public static Margin startEndDimenId(@DimenRes int startDimenId,
                                         @DimenRes int endDimenId) {
        return size(
                DimenValue.startDimenId(startDimenId),
                DimenValue.endDimenId(endDimenId)
        );
    }

    public static Margin dimenId(@DimenRes int dimenId) {
        int dimen = ResourceUtils.getDimen(dimenId);
        return size(dimen, dimen, dimen, dimen);
    }

    public static Margin dimenId(@DimenRes int topDimenId,
                                 @DimenRes int bottomDimenId,
                                 @DimenRes int startDimenId,
                                 @DimenRes int endDimenId) {
        return size(
                DimenValue.topDimenId(topDimenId),
                DimenValue.bottomDimenId(bottomDimenId),
                DimenValue.startDimenId(startDimenId),
                DimenValue.endDimenId(endDimenId)
            );
    }

    public static Margin top(@NonNull String top) {
        return size(
                DimenValue.topSize(top)
        );
    }

    public static Margin bottom(@NonNull String bottom) {
        return size(
                DimenValue.bottomSize(bottom)
        );
    }

    public static Margin topBottom(@NonNull String margin) {
        int dimen = WidgetUtils.dimenInt(margin);
        return topBottom(dimen, dimen);
    }

    public static Margin topBottom(@NonNull String top,
                                   @NonNull String bottom) {
        return size(
                DimenValue.topSize(top),
                DimenValue.bottomSize(bottom)
        );
    }

    public static Margin start(@NonNull String start) {
        return size(
                DimenValue.startSize(start)
        );
    }

    public static Margin end(@NonNull String end) {
        return size(
                DimenValue.endSize(end)
        );
    }

    public static Margin startEnd(@NonNull String margin) {
        int dimen = WidgetUtils.dimenInt(margin);
        return startEnd(dimen, dimen);
    }

    public static Margin startEnd(@NonNull String start,
                                  @NonNull String end) {
        return size(
                DimenValue.startSize(start),
                DimenValue.endSize(end)
        );
    }

    public static Margin size(@NonNull String margin) {
        int dimen = WidgetUtils.dimenInt(margin);
        return size(dimen, dimen, dimen, dimen);
    }

    public static Margin size(@NonNull String top,
                              @NonNull String bottom,
                              @NonNull String start,
                              @NonNull String end) {
        return size(
                DimenValue.topSize(top),
                DimenValue.bottomSize(bottom),
                DimenValue.startSize(start),
                DimenValue.endSize(end)
            );
    }

    public static Margin top(int top) {
        return size(
                DimenValue.topSize(top)
            );
    }

    public static Margin bottom(int bottom) {
        return size(
                DimenValue.bottomSize(bottom)
        );
    }

    public static Margin topBottom(int margin) {
        return topBottom(margin, margin);
    }

    public static Margin topBottom(int top, int bottom) {
        return size(
                DimenValue.topSize(top),
                DimenValue.bottomSize(bottom)
        );
    }

    public static Margin start(int start) {
        return size(
                DimenValue.startSize(start)
        );
    }

    public static Margin end(int end) {
        return size(
                DimenValue.endSize(end)
        );
    }

    public static Margin startEnd(int margin) {
        return startEnd(margin, margin);
    }

    public static Margin startEnd(int start, int end) {
        return size(
                DimenValue.startSize(start),
                DimenValue.endSize(end)
        );
    }

    public static Margin size(int margin) {
        return size(margin, margin, margin, margin);
    }

    public static Margin size(int top, int bottom, int start, int end) {
        return size(
                DimenValue.topSize(top),
                DimenValue.bottomSize(bottom),
                DimenValue.startSize(start),
                DimenValue.endSize(end)
            );
    }

    public static Margin size(@NonNull DimenValue... values) {
        return new Margin(values);
    }

    private Margin(DimenValue... values) {
        super(values);
    }

    @Override
    protected void takeEffect(@NonNull ViewHelper<? extends View> helper, @NonNull Value[] values) {
        helper.getViewNulls().doNotNull(view -> setMarginLayoutParams(view.getLayoutParams(), values));
    }

    private void setMarginLayoutParams(@NonNull ViewGroup.LayoutParams layoutParams,
                                       @NonNull Value[] values) {
        if(layoutParams instanceof ViewGroup.MarginLayoutParams) {
            ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) layoutParams;
            EasyUtils.forEach(values, value -> {
                DimenValue dimenValue = value instanceof DimenValue ? (DimenValue) value : null;
                if(dimenValue != null) {
                    setMarginLayoutParams(marginLayoutParams, dimenValue);
                }
            });
        }
    }

    private void setMarginLayoutParams(@NonNull ViewGroup.MarginLayoutParams marginLayoutParams,
                                       @NonNull DimenValue dimenValue) {
        switch (dimenValue.direction()) {
            case DimenValue.TOP:
                marginLayoutParams.topMargin = dimenValue.value();
                break;
            case DimenValue.BOTTOM:
                marginLayoutParams.bottomMargin = dimenValue.value();
                break;
            case DimenValue.START:
                marginLayoutParams.setMarginStart(dimenValue.value());
                break;
            case DimenValue.END:
                marginLayoutParams.setMarginEnd(dimenValue.value());
                break;
            default:
                break;
        }
    }
}
